package com.example.gobang.api;

import com.example.gobang.game.MatchRequest;
import com.example.gobang.game.MatchResponse;
import com.example.gobang.game.Matcher;
import com.example.gobang.game.OnlineUserManager;
import com.example.gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * @author vivi
 * @description
 * @date 2024/6/29
 */
// 处理匹配功能中的 websocket 请求
@Component
public class MatchAPI extends TextWebSocketHandler {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished (WebSocketSession session) throws Exception {
        // 玩家上线 -- 加入到 OnlineUSerManager 中
        try{
            // 1 获取用户的身份信息
            User user = (User) session.getAttributes().get("user");
            // 2 先判断当前用户是否登陆过， 如果已经在线， 则不再继续后续操作
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession != null) {
                // 用户已经登录
                // 告诉客户端， 正在进行重复登录
                MatchResponse response = new MatchResponse();
                response.setOk(true);
                response.setReason("当前禁止多开！");
                response.setMessage("repeatConnection");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                // 返回特殊的message，由客户端进行处理
                // session.close();
                return;
            }
            // 3 把玩家设置成在线状态
            onlineUserManager.enterGameHall(user.getUserId(), session);
            System.out.println("玩家" + user.getUsername() + "进入游戏大厅");
        }catch (NullPointerException e){
            System.out.println("[MatchAPI.afterConnectionEstablished] 当前用户未登录！");
//            e.printStackTrace();
            // 出现空指针异常， 说明用户未登录
            // 返回 用户尚未登录 这个信息
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("您尚未登录，不能进行后续匹配功能！");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    protected void handleTextMessage (WebSocketSession session, TextMessage message) throws Exception {
        // 实现处理开始匹配请求和处理停止匹配请求
        User user = (User) session.getAttributes().get("user");
        // 获取客户端给服务器发送的数据
        String payload = message.getPayload();
        MatchRequest request = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")) {
            // 把玩家加入到匹配队列
            matcher.add(user);
            response.setOk(true);
            response.setMessage("startMatch");
        } else if (request.getMessage().equals("stopMatch")) {
            // 退出匹配队列
            matcher.remove(user);
            response.setOk(true);
            response.setMessage("stopMatch");
        } else {
            // 非法
            response.setOk(false);
            response.setMessage("非法的匹配请求");
        }
        String jsonString = objectMapper.writeValueAsString(response);
        session.sendMessage(new TextMessage(jsonString));
    }

    @Override
    public void handleTransportError (WebSocketSession session, Throwable exception) throws Exception {
        // 玩家下线 -- 从 OnlineUSerManager 中删除
        try {
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(user.getUserId());
            }
            // 如果玩家正在匹配中， 但是 websocket 连接断开了
            matcher.remove(user);
        }catch(NullPointerException e){
            System.out.println("[MatchAPI.handleTransportError] 当前用户未登录！");
//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录，不能进行后续匹配功能！");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    public void afterConnectionClosed (WebSocketSession session, CloseStatus status) throws Exception {
        try {
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(user.getUserId());
            }
            // 如果玩家正在匹配中， 但是 websocket 连接断开了
            matcher.remove(user);
        }catch(NullPointerException e){
            System.out.println("[MatchAPI.afterConnectionClosed] 当前用户未登录！");
//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录，不能进行后续匹配功能！");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
}












